﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace DaedalusEngine.Source
{
    public class Actor : IActor, IGameObject
    {
        #region Attributes

        
        private Texture2D texture;
        public Vector2 position;
        private Vector2 origin;
        private float rotation;
        private Rectangle bounds;
        private float scale;
        private float alpha;
        private Color color;
        private Color[] textureData;
        private bool isVisible;

        private Dictionary<string, FrameAnimation> animations;
        private string currentAnimation;
        private int spriteWidth;
        private int spriteHeight;
        private bool isAlive;
        private bool isAnimating;
       

        #endregion

        #region Properties

        public Texture2D Texture { get { return texture; } set { texture = value; } }
        public Vector2 Position { get { return position; } set { position = value; } }
        public Vector2 Origin { get { return origin; } set { origin = value; } }
        public Rectangle Bounds { get { return bounds; } set { bounds = value; } }
        public float Rotation { get { return rotation; } set { rotation = value; } }
        public float Scale { get { return scale; } set { scale = value; } }
        public float Alpha { get { return alpha; } set { alpha = value; } }
        public Color Color { get { return color; } set { color = value; } }
        public Color[] TextureData { get { return textureData; } }
        public bool IsVisible { get { return isVisible; } set { isVisible = value; } }


        public int SpriteWidth { get { return spriteWidth; } }
        public int SpriteHeight { get { return spriteHeight; } }
        public bool IsAlive 
        { 
            get { return isAlive; } 
            set { isAlive = value; if (isAlive == false) IsVisible = false; } 
        }
        public bool IsAnimating { get { return isAnimating; } set { isAnimating = value; } }
        public FrameAnimation CurrentFrameAnimation
        {
            get
            {
                if (!string.IsNullOrEmpty(currentAnimation))
                    return animations[currentAnimation];
                else
                    return null;
            }
        }
        public string CurrentAnimation
        {
            get { return currentAnimation; }
            set
            {
                if (animations.ContainsKey(value))
                {
                    currentAnimation = value;
                    animations[currentAnimation].PlayCount = 0;
                    animations[currentAnimation].CurrentFrame = 0;
                }
            }
        }

        #endregion

        #region Constructors

        public Actor(Texture2D texture, Vector2 position, float rotation, float scale, float alpha, Color color)
        {
            Texture = texture;
            Position = position;
            animations = new Dictionary<string, FrameAnimation>();
            IsAnimating = true;
            IsVisible = true;
            IsAlive = true;
            Origin = new Vector2((float)(texture.Width / 2), (float)(texture.Height / 2));
            Rotation = rotation;
            Scale = scale;
            Alpha = alpha;
            Color = color;
        }

        #endregion

        #region Methods

        public virtual void Update(GameTime gameTime)
        {
            if (IsAlive)
            {
                if (IsAnimating)
                {
                    if (CurrentAnimation == null) //If for some reason out current animation is null
                    {
                        if (animations.Count > 0) //If there is an animation in our collection
                        {
                            string[] keys = new string[animations.Count];
                            animations.Keys.CopyTo(keys, 0);
                            CurrentAnimation = keys[0]; //Set the current animation to the first animation in our collection
                        }
                        else
                            return;   //Return if there is no animation to play
                    }

                    CurrentFrameAnimation.Update(gameTime);  //Update the current animation

                    //If there is a next animation stored in our current animation
                    if (!string.IsNullOrEmpty(CurrentFrameAnimation.NextAnimation))
                    {
                        if (CurrentFrameAnimation.PlayCount > 0) //If the current animation has played at least once
                        {
                            //We now set the current animation to that of the next animation
                            CurrentAnimation = CurrentFrameAnimation.NextAnimation;
                        }
                    }
                }
            }
        }

        public virtual void Draw(SpriteBatch spriteBatch)
        {
            if (IsVisible)
            {
                spriteBatch.Draw(Texture, Position, CurrentFrameAnimation.FrameRectangle,
                    Color * Alpha, Rotation, Origin, Scale, SpriteEffects.None, 0.0f);
            }
        }

        public void SetBoundRect(int bufferX, int bufferY)
        {
            Bounds = new Rectangle((int)(position.X),
                (int)(position.Y), spriteWidth + bufferX, spriteHeight + bufferY);
        }

        public bool RectCollidesWith(IGameObject gObj)
        {
            if (Bounds.Intersects(gObj.Bounds))
            {
                Console.WriteLine("Rectangle Collision detected");
                return true;
            }
            else
                return false;
        }

        public Vector2 GetPosition() { return position; }

        public bool PixelCollidesWith(IGameObject gObj) { return false; }

        public void Move(float x, float y)
        {
            position.X += x;
            position.Y += y;
        }

        public void AddAnimation(string name, int x, int y, int width, int height,
            int frames, float frameLength, string nextAnimation)
        {
            animations.Add(name, new FrameAnimation(x, y, width, height, frames, frameLength, nextAnimation));
            spriteWidth = width;
            spriteHeight = height;
            Origin = new Vector2((float)(spriteWidth / 2), (float)(spriteHeight / 2));
        }

        public FrameAnimation GetAnimationByName(string name)
        {
            if (animations.ContainsKey(name))
                return animations[name];
            else
                return null;
        }

        public void Die()
        {
            IsAlive = false;
        }


        
        

        #endregion
    }
}
